﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Xml.Linq;
using System.Collections;
using System.Reflection;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using FreedomX2.Core.Log;

namespace FreedomX2.Core.DataBase
{

    /// <summary>
    /// 数据库类型枚举
    /// </summary>
    public enum EsDataBaseType
    {
        SqlServerClient,
        OracleClient,
        AccessClient,
        MySqlClient,
        SyBaseClient,
        OtherClient
    }

    /// <summary>
    /// 数据中心类
    /// </summary>
    public class EsDataCenter
    {
        //private bool _DisplayLog = true;

        public bool DisplayLog
        {
            get { return Envior.Ment.ISLOGSTART; }
            set { Envior.Ment.ISLOGSTART = value; }
        }

        /// <summary>
        /// 将DataSet序列化成byte[]
        /// </summary>
        /// <param name="dsOriginal"></param>
        /// <returns></returns>
        public static byte[] GetBinaryFormatData(DataSet dsOriginal)
        {
            byte[] binaryDataResult = null;
            MemoryStream memStream = new MemoryStream();

            //以二进制格式将对象或整个连接对象图形序列化和反序列化。
            IFormatter brFormatter = new BinaryFormatter();

            //dsOriginal.RemotingFormat 为远程处理期间使用的DataSet 获取或设置 SerializtionFormat         
            //SerializationFormat.Binary      将字符串比较方法设置为使用严格的二进制排序顺序
            dsOriginal.RemotingFormat = SerializationFormat.Binary;

            //把字符串以二进制放进memStream中
            brFormatter.Serialize(memStream, dsOriginal);
            //转为byte数组
            binaryDataResult = memStream.ToArray();

            memStream.Close();
            memStream.Dispose();
            return binaryDataResult;
        }

        /// <summary>
        /// 将字节数组反序列化成DataSet对象
        /// </summary>
        /// <param name="binaryData">字节数组</param>
        /// <returns>DataSet对象</returns>
        public static DataSet RetrieveDataSet(byte[] binaryData)
        {
            DataSet ds = null;
            MemoryStream memStream = new MemoryStream(binaryData, true);

            IFormatter brFormatter = new BinaryFormatter();
            ds = (DataSet)brFormatter.Deserialize(memStream);
            return ds;
        }

        /// <summary>
        /// 将object格式化成字节数组byte[]
        /// </summary>
        /// <param name="dsOriginal">object对象</param>
        /// <returns>字节数组</returns>
        public static byte[] GetBinaryFormatData(object dsOriginal)
        {
            byte[] binaryDataResult = null;
            MemoryStream memStream = new MemoryStream();
            IFormatter brFormatter = new BinaryFormatter();

            brFormatter.Serialize(memStream, dsOriginal);
            binaryDataResult = memStream.ToArray();

            memStream.Close();
            memStream.Dispose();
            return binaryDataResult;
        }

        /// <summary>
        /// 将byte[]字节数组反序列化成object对象
        /// </summary>
        /// <param name="binaryData">字节数组</param>
        /// <returns>object对象</returns>
        public static object RetrieveObject(byte[] binaryData)
        {
            MemoryStream memStream = new MemoryStream(binaryData);
            IFormatter brFormatter = new BinaryFormatter();
            Object obj = brFormatter.Deserialize(memStream);
            return obj;
        }

        /// <summary>
        /// 获取或设置数据库类型
        /// </summary>
        public EsDataBaseType DataBaseType { get; set; }

        /// <summary>
        /// 获取或设置数据库连接
        /// </summary>
        public IDbConnection DataBaseConnection { get; set; }

        /// <summary>
        /// 通过数据库类型实例化
        /// </summary>
        /// <param name="_dbtype"></param>
        public EsDataCenter(EsDataBaseType _dbtype)
        {
            DataBaseType = _dbtype;
        }

        /// <summary>
        /// 通过连接字符串构造数据库连接
        /// </summary>
        /// <param name="_dbconstr"></param>
        /// <returns></returns>
        public IDbConnection EsDataBaseInit(string _dbconstr)
        {
            IDbConnection reIConn = null;
            switch (DataBaseType)
            {
                case EsDataBaseType.SqlServerClient:
                    reIConn = new SqlConnection(_dbconstr.ToString());
                    break;
                case EsDataBaseType.OracleClient:
                    //reIConn = new OracleConnection(_dbconstr.ToString());
                    break;
                case EsDataBaseType.MySqlClient:
                    reIConn = new MySql.Data.MySqlClient.MySqlConnection(_dbconstr.ToString());
                    break;
                default:
                    reIConn = null;
                    break;
            }

            if (reIConn != null)
            {
                DataBaseConnection = reIConn;
                return reIConn;
            }
            else
                throw new Exception("EsDataBaseInit field!");
        }

        /// <summary>
        /// 对当前实例数据库连接测试
        /// </summary>
        /// <param name="_Iec"></param>
        /// <returns></returns>
        public bool EsDataBaseTest(IDbConnection _Iec)
        {
            try
            {
                if (_Iec.State == ConnectionState.Closed)
                    _Iec.Open();
                if (_Iec.State == ConnectionState.Open)
                {
                    _Iec.Close();
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// 构造语句所需的DataReader
        /// </summary>
        /// <param name="_dbSqlQuary"></param>
        /// <returns></returns>
        public IDataReader EsDataRun_ReturnReader(string _dbSqlQuary)
        {
            if (DataBaseConnection.State == ConnectionState.Closed)
                DataBaseConnection.Open();
            if (DataBaseConnection.State != ConnectionState.Open)
                throw new Exception("DataBaseConnection Open field!");

            IDataReader reIReader = null;
            switch (DataBaseType)
            {
                case EsDataBaseType.SqlServerClient:

                    SqlCommand _sc = new SqlCommand(_dbSqlQuary, DataBaseConnection as SqlConnection);
                    reIReader = _sc.ExecuteReader();
                    break;
                case EsDataBaseType.OracleClient:
                    //OracleCommand _oc = new OracleCommand(_dbSqlQuary, DataBaseConnection as OracleConnection);
                    //reIReader = _oc.ExecuteReader();
                    break;
                case EsDataBaseType.MySqlClient:
                    MySql.Data.MySqlClient.MySqlCommand _mc = new MySql.Data.MySqlClient.MySqlCommand(_dbSqlQuary, DataBaseConnection as MySql.Data.MySqlClient.MySqlConnection);
                    reIReader = _mc.ExecuteReader();
                    break;
                default:
                    reIReader = null;
                    break;
            }
            if (reIReader != null)
            {
                //DataBaseConnection.Close();
                return reIReader;
            }
            else
                throw new Exception("EsDataRun_ReturnReader field!");
        }

        /// <summary>
        /// 构造语句所需的DataAdapter
        /// </summary>
        /// <param name="_dbSqlQuary"></param>
        /// <returns></returns>
        public IDataAdapter EsDataRun_ReturnAdapter(string _dbSqlQuary)
        {
            if (DisplayLog)
            {
                Console.WriteLine(DateTime.Now.ToString() + "：EsDataRun_ReturnAdapter执行语句：" + _dbSqlQuary);
                ("EsDataRun_ReturnAdapter执行语句：" + _dbSqlQuary).l();
            }
            if (DataBaseConnection.State == ConnectionState.Closed)
                DataBaseConnection.Open();
            if (DataBaseConnection.State != ConnectionState.Open)
                throw new Exception("DataBaseConnection Open field!");

            IDataAdapter reIAdapter = null;
            switch (DataBaseType)
            {
                case EsDataBaseType.SqlServerClient:
                    SqlCommand _sc = new SqlCommand(_dbSqlQuary, DataBaseConnection as SqlConnection);
                    SqlDataAdapter _sda = new SqlDataAdapter(_sc);
                    reIAdapter = _sda;
                    break;
                case EsDataBaseType.OracleClient:
                    //OracleCommand _oc = new OracleCommand(_dbSqlQuary, DataBaseConnection as OracleConnection);
                    //OracleDataAdapter _oda = new OracleDataAdapter(_oc);
                    //reIAdapter = _oda;
                    break;
                case EsDataBaseType.MySqlClient:
                    MySql.Data.MySqlClient.MySqlCommand _mc = new MySql.Data.MySqlClient.MySqlCommand(_dbSqlQuary, DataBaseConnection as MySql.Data.MySqlClient.MySqlConnection);
                    MySql.Data.MySqlClient.MySqlDataAdapter _mda = new MySql.Data.MySqlClient.MySqlDataAdapter(_mc);
                    reIAdapter = _mda;
                    break;
                default:
                    reIAdapter = null;
                    break;
            }
            if (reIAdapter != null)
            {
                DataBaseConnection.Close();
                return reIAdapter;
            }
            else
                throw new Exception("EsDataRun_ReturnAdapter field!");
        }

        /// <summary>
        /// 构造语句所需的DataCommand
        /// </summary>
        /// <param name="_dbSqlQuary"></param>
        /// <returns></returns>
        public IDbCommand EsDataRun_ReturnCommand(string _dbSqlQuary)
        {
            if (DisplayLog)
            {
                Console.WriteLine(DateTime.Now.ToString() + "：EsDataRun_ReturnCommand执行语句：" + _dbSqlQuary);
                ("EsDataRun_ReturnCommand执行语句：" + _dbSqlQuary).l();
            }
            if (DataBaseConnection.State == ConnectionState.Closed)
                DataBaseConnection.Open();
            if (DataBaseConnection.State != ConnectionState.Open)
                throw new Exception("DataBaseConnection Open field!");

            IDbCommand reICmd = null;
            switch (DataBaseType)
            {
                case EsDataBaseType.SqlServerClient:
                    SqlCommand _sc = new SqlCommand(_dbSqlQuary, DataBaseConnection as SqlConnection);
                    reICmd = _sc;
                    break;
                case EsDataBaseType.OracleClient:
                    //OracleCommand _oc = new OracleCommand(_dbSqlQuary, DataBaseConnection as OracleConnection);
                    //reICmd = _oc;
                    break;
                case EsDataBaseType.MySqlClient:
                    MySql.Data.MySqlClient.MySqlCommand _mc = new MySql.Data.MySqlClient.MySqlCommand(_dbSqlQuary, DataBaseConnection as MySql.Data.MySqlClient.MySqlConnection);
                    reICmd = _mc;
                    break;
                default:
                    reICmd = null;
                    break;
            }
            if (reICmd != null)
            {
                DataBaseConnection.Close();
                return reICmd;
            }
            else
                throw new Exception("EsDataRun_ReturnCommand field!");
        }

        /// <summary>
        /// 构造存储过程所需的DataReader
        /// </summary>
        /// <param name="param"></param>
        /// <param name="procedureName"></param>
        /// <returns></returns>
        public IDataReader EsDataRunProcedure_ReturnReader(string procedureName, List<EsDataParameter> param)
        {
            if (DisplayLog)
            {
                Console.WriteLine(DateTime.Now.ToString() + "：EsDataRunProcedure_ReturnReader执行语句：" + procedureName);
                ("EsDataRunProcedure_ReturnReader执行语句：" + procedureName).l();
            }
            if (DataBaseConnection.State == ConnectionState.Closed)
                DataBaseConnection.Open();
            if (DataBaseConnection.State != ConnectionState.Open)
                throw new Exception("DataBaseConnection Open field!");
            IDbCommand idc = null;
            IDataReader reIReader = null;
            switch (DataBaseType)
            {
                case EsDataBaseType.SqlServerClient:

                    SqlCommand _sc = new SqlCommand();
                    _sc.Connection = DataBaseConnection as SqlConnection;
                    foreach (EsDataParameter edp in param)
                    {
                        _sc.Parameters.Add(new SqlParameter()
                        {
                            DbType = edp.ParameterType,
                            ParameterName = edp.ParameterName,
                            Size = edp.ParameterLength,
                            Direction = edp.ParameterInOutType,
                            Value = edp.ParameterValue
                        });
                    }
                    idc = _sc;
                    break;
                case EsDataBaseType.OracleClient:
                    //OracleCommand _oc = new OracleCommand();
                    //_oc.Connection = DataBaseConnection as OracleConnection;
                    //foreach (EsDataParameter edp in param)
                    //{
                    //    _oc.Parameters.Add(new OracleParameter()
                    //    {
                    //        DbType = edp.ParameterType,
                    //        ParameterName = edp.ParameterName,
                    //        Size = edp.ParameterLength,
                    //        Direction = edp.ParameterInOutType,
                    //        Value = edp.ParameterValue
                    //    });
                    //}
                    //idc = _oc;
                    break;
                case EsDataBaseType.MySqlClient:
                    MySql.Data.MySqlClient.MySqlCommand _mc = new MySql.Data.MySqlClient.MySqlCommand();
                    _mc.Connection = DataBaseConnection as MySql.Data.MySqlClient.MySqlConnection;
                    foreach (EsDataParameter edp in param)
                    {
                        _mc.Parameters.Add(new MySql.Data.MySqlClient.MySqlParameter()
                        {
                            DbType = edp.ParameterType,
                            ParameterName = edp.ParameterName,
                            Size = edp.ParameterLength,
                            Direction = edp.ParameterInOutType,
                            Value = edp.ParameterValue
                        });
                    }
                    idc = _mc;
                    break;
                default:
                    reIReader = null;
                    break;
            }
            if (idc != null)
            {
                idc.CommandType = CommandType.StoredProcedure;
                idc.CommandText = procedureName;
                reIReader = idc.ExecuteReader();
            }
            else
                throw new Exception("EsDataRunProcedure_ReturnReader Load DataCommand field!");
            if (reIReader != null)
            {
                //DataBaseConnection.Close();
                return reIReader;
            }
            else
                throw new Exception("EsDataRunProcedure_ReturnReader field!");
        }

        /// <summary>
        /// 构造存储过程所需的DataCommand
        /// </summary>
        /// <param name="procedureName"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public IDbCommand EsDataRunProcedure_ReturnCommand(string procedureName, List<EsDataParameter> param)
        {
            if (DisplayLog)
            {
                Console.WriteLine(DateTime.Now.ToString() + "：EsDataRunProcedure_ReturnCommand执行语句：" + procedureName);
                ("EsDataRunProcedure_ReturnCommand执行语句：" + procedureName).l();
            }
            if (DataBaseConnection.State == ConnectionState.Closed)
                DataBaseConnection.Open();
            if (DataBaseConnection.State != ConnectionState.Open)
                throw new Exception("DataBaseConnection Open field!");
            IDbCommand idc = null;
            IDataReader reIReader = null;
            switch (DataBaseType)
            {
                case EsDataBaseType.SqlServerClient:

                    SqlCommand _sc = new SqlCommand();
                    _sc.Connection = DataBaseConnection as SqlConnection;
                    foreach (EsDataParameter edp in param)
                    {
                        _sc.Parameters.Add(new SqlParameter()
                        {
                            DbType = edp.ParameterType,
                            ParameterName = edp.ParameterName,
                            Size = edp.ParameterLength,
                            Direction = edp.ParameterInOutType,
                            Value = edp.ParameterValue
                        });
                    }
                    idc = _sc;
                    break;
                case EsDataBaseType.OracleClient:
                    //OracleCommand _oc = new OracleCommand();
                    //_oc.Connection = DataBaseConnection as OracleConnection;
                    //foreach (EsDataParameter edp in param)
                    //{
                    //    _oc.Parameters.Add(new OracleParameter()
                    //    {
                    //        DbType = edp.ParameterType,
                    //        ParameterName = edp.ParameterName,
                    //        Size = edp.ParameterLength,
                    //        Direction = edp.ParameterInOutType,
                    //        Value = edp.ParameterValue
                    //    });
                    //}
                    //idc = _oc;
                    break;
                case EsDataBaseType.MySqlClient:
                    MySql.Data.MySqlClient.MySqlCommand _mc = new MySql.Data.MySqlClient.MySqlCommand();
                    _mc.Connection = DataBaseConnection as MySql.Data.MySqlClient.MySqlConnection;
                    foreach (EsDataParameter edp in param)
                    {
                        _mc.Parameters.Add(new MySql.Data.MySqlClient.MySqlParameter()
                        {
                            DbType = edp.ParameterType,
                            ParameterName = edp.ParameterName,
                            Size = edp.ParameterLength,
                            Direction = edp.ParameterInOutType,
                            Value = edp.ParameterValue
                        });
                    }
                    idc = _mc;
                    break;
                default:
                    reIReader = null;
                    break;
            }
            if (idc != null)
            {
                idc.CommandType = CommandType.StoredProcedure;
                idc.CommandText = procedureName;
                reIReader = idc.ExecuteReader();

            }
            else
                throw new Exception("EsDataRunProcedure_ReturnReader Load DataCommand field!");
            if (reIReader != null)
            {
                //DataBaseConnection.Close();
                return idc;
            }
            else
                throw new Exception("EsDataRunProcedure_ReturnReader field!");
        }
    }

    /// <summary>
    /// Data参数实体类
    /// </summary>
    public class EsDataParameter
    {
        public string ParameterName { get; set; }
        public DbType ParameterType { get; set; }
        public string ParameterValue { get; set; }
        public int ParameterLength { get; set; }
        public ParameterDirection ParameterInOutType { get; set; }
        public EsDataParameter() { }
        public EsDataParameter(string paramName) { ParameterName = paramName; }
        public EsDataParameter(string paramName, DbType paramType) { ParameterName = paramName; ParameterType = paramType; }
        public EsDataParameter(string paramName, DbType paramType, int paramSize) { ParameterName = paramName; ParameterType = paramType; ParameterLength = paramSize; }
        public EsDataParameter(string paramName, DbType paramType, int paramSize, ParameterDirection paramDirection) { ParameterName = paramName; ParameterType = paramType; ParameterLength = paramSize; ParameterInOutType = paramDirection; }
    }

    /// <summary>
    /// 数据构造类
    /// </summary>
    public class EsDataConstructer
    {
        /// <summary>
        /// 获取或设置数据结构XML路径
        /// </summary>
        public string ConstructerXMLPath { get; set; }

        /// <summary>
        /// 获取或设置数据结构XML文件名(包含扩展名)
        /// </summary>
        public string ConstructerXMLName { get; set; }

        /// <summary>
        /// 构造数据结构XML文件路径
        /// </summary>
        /// <param name="_XMLDictory"></param>
        public EsDataConstructer(string _XMLDictory)
        {
            ConstructerXMLPath = _XMLDictory;
        }

        /// <summary>
        /// 构造数据结构XML文件路径+文件名称(包含扩展名)
        /// </summary>
        /// <param name="_XMLDictory"></param>
        /// <param name="_XMLName"></param>
        public EsDataConstructer(string _XMLDictory, string _XMLName)
        {
            ConstructerXMLPath = _XMLDictory;
            ConstructerXMLName = _XMLName;
        }

        /// <summary>
        /// 构造表
        /// </summary>
        /// <param name="_elementTableName"></param>
        /// <param name="_idr"></param>
        /// <returns></returns>
        public List<List<Object[]>> Constructer(string _elementTableName, IDataReader _idr)
        {
            List<List<Object[]>> reList = new List<List<Object[]>>();
            if (ConstructerXMLPath == null)
            {
                throw new Exception("Constructer ConstructerXMLPath is Null");
            }
            if (ConstructerXMLName == null)
            {
                throw new Exception("Constructer ConstructerXMLName is Null");
            }
            XDocument xdoc = XDocument.Load(ConstructerXMLPath + ConstructerXMLName);
            if (xdoc != null)
            {
                string strDbType = "";
                if (xdoc.Root.Attribute("dbtype") != null)
                    strDbType = xdoc.Root.Attribute("dbtype").Value;
                var xtable = (from XElement _table in xdoc.Root.Elements("Table")
                              where _table != null &&
                              _table.Attribute("name") != null &&
                              _table.Attribute("name").Value == _elementTableName &&
                              _table.Nodes().Count() > 0
                              select _table).ToList();
                if (xtable != null && xtable.Count == 1 && xtable.Nodes() != null && xtable.Nodes().Count() > 0)
                {
                    while (_idr.Read())
                    {
                        List<Object[]> _tempList = new List<Object[]>();
                        foreach (XElement xelement in xtable.Nodes())
                        {
                            Object[] _tempObject = new Object[] { new Object(), new Object() };
                            if (xelement.Attribute("name") != null)
                                _tempObject[0] = xelement.Attribute("name").Value;
                            if (xelement.Attribute("type") != null)
                                if (_idr[_tempObject[0].ToString()] != null && _idr[_tempObject[0].ToString()].ToString() != "")
                                    _tempObject[1] = getObjectbyDataType(strDbType, _idr[_tempObject[0].ToString()].ToString(), xelement.Attribute("type").Value);
                            _tempList.Add(_tempObject);
                        }
                        reList.Add(_tempList);
                    }
                }
                else
                    throw new Exception("Constructer Load TableName :" + _elementTableName + " field!");
            }
            else
                throw new Exception("Constructer Load XML field!");
            if (reList.Count > 0)
                return reList;
            else
                throw new Exception("Constructer May be the data is null Error!");
        }

        /// <summary>
        /// 构造表 通过DataRader返回数据实体类型集合
        /// </summary>
        /// <param name="_elementTableName"></param>
        /// <param name="_idr"></param>
        /// <param name="_objType"></param>
        /// <returns></returns>
        public List<Object> Constructer(string _elementTableName, IDataReader _idr, Type _objType)
        {
            List<Object> reList = new List<object>();
            if (ConstructerXMLPath == null)
            {
                throw new Exception("Constructer ConstructerXMLPath is Null");
            }
            if (ConstructerXMLName == null)
            {
                throw new Exception("Constructer ConstructerXMLName is Null");
            }
            XDocument xdoc = XDocument.Load(ConstructerXMLPath + ConstructerXMLName);
            if (xdoc != null)
            {
                try
                {
                    string strDbType = "";
                    if (xdoc.Root.Attribute("dbtype") != null)
                        strDbType = xdoc.Root.Attribute("dbtype").Value;
                    var xtable = (from XElement _table in xdoc.Root.Elements("Table")
                                  where _table != null &&
                                  _table.Attribute("name") != null &&
                                  _table.Attribute("name").Value == _elementTableName &&
                                  _table.Nodes().Count() > 0
                                  select _table).ToList();
                    if (xtable != null && xtable.Count == 1 && xtable.Nodes() != null && xtable.Nodes().Count() > 0)
                    {

                        while (_idr.Read())
                        {
                            object obj = Activator.CreateInstance(_objType);

                            foreach (XElement xelement in xtable.Nodes())
                            {
                                string attid = "";
                                if (xelement.Attribute("name") != null)
                                {
                                    attid = xelement.Attribute("name").Value;
                                }
                                object attvalue = null;
                                if (xelement.Attribute("type") != null)
                                    if (_idr[attid] != null && _idr[attid].ToString() != "")
                                        attvalue = getObjectbyDataType(strDbType, _idr[attid].ToString(), xelement.Attribute("type").Value);
                                if (attid != "" && attvalue != null)
                                {
                                    PropertyInfo pi = _objType.GetProperty(attid);
                                    if (pi != null)
                                        pi.SetValue(obj, attvalue, null);
                                    else
                                        throw new Exception("Constructer Load Property:" + attid + " field!");
                                }
                            }
                            reList.Add(obj);
                        }
                    }
                    else
                        throw new Exception("Constructer Load TableName :" + _elementTableName + " field!");
                }
                catch (Exception _ex)
                {
                    throw _ex;
                }
            }
            else
                throw new Exception("Constructer Load XML field!");
            if (reList.Count > 0)
                return reList;
            else
                throw new Exception("Constructer May be the data is null Error!");
        }

        /// <summary>
        /// 构造表 通过DataSet返回数据实体类型集合
        /// </summary>
        /// <param name="_elementTableName"></param>
        /// <param name="_ds"></param>
        /// <param name="_objType"></param>
        /// <returns></returns>
        public List<Object> Constructer(string _elementTableName, DataSet _ds, Type _objType)
        {
            List<Object> reList = new List<object>();
            if (ConstructerXMLPath == null)
            {
                throw new Exception("Constructer ConstructerXMLPath is Null");
            }
            if (ConstructerXMLName == null)
            {
                throw new Exception("Constructer ConstructerXMLName is Null");
            }
            XDocument xdoc = XDocument.Load(ConstructerXMLPath + ConstructerXMLName);
            if (xdoc != null)
            {
                try
                {
                    string strDbType = "";
                    if (xdoc.Root.Attribute("dbtype") != null)
                        strDbType = xdoc.Root.Attribute("dbtype").Value;
                    var xtable = (from XElement _table in xdoc.Root.Elements("Table")
                                  where _table != null &&
                                  _table.Attribute("name") != null &&
                                  _table.Attribute("name").Value == _elementTableName &&
                                  _table.Nodes().Count() > 0
                                  select _table).ToList();
                    if (xtable != null && xtable.Count == 1 && xtable.Nodes() != null && xtable.Nodes().Count() > 0)
                    {

                        if (_ds.Tables.Count > 0)
                        {
                            if (_ds.Tables[0].Rows.Count > 0)
                            {
                                foreach (DataRow _dr in _ds.Tables[0].Rows)
                                {
                                    object obj = Activator.CreateInstance(_objType);

                                    foreach (XElement xelement in xtable.Nodes())
                                    {
                                        string attid = "";
                                        if (xelement.Attribute("name") != null)
                                        {
                                            attid = xelement.Attribute("name").Value;
                                        }
                                        object attvalue = null;
                                        if (xelement.Attribute("type") != null)
                                            if (_dr[attid] != null && _dr[attid].ToString() != "")
                                                attvalue = getObjectbyDataType(strDbType, _dr[attid].ToString(), xelement.Attribute("type").Value);
                                        if (attid != "" && attvalue != null)
                                        {
                                            PropertyInfo pi = _objType.GetProperty(attid);
                                            if (pi != null)
                                                pi.SetValue(obj, attvalue, null);
                                            //else
                                            //    throw new Exception("Constructer Load Property:" + attid + " field!");
                                        }
                                    }
                                    reList.Add(obj);
                                }
                            }
                        }
                    }
                    else
                        throw new Exception("Constructer Load TableName :" + _elementTableName + " field!");
                }
                catch (Exception _ex)
                {
                    throw _ex;
                }
            }
            else
                throw new Exception("Constructer Load XML field!");
            if (reList.Count > 0)
                return reList;
            else
                throw new Exception("Constructer May be the data is null Error!");
        }

        /// <summary>
        /// 构造表从其他文件
        /// </summary>
        /// <param name="_elementTableName"></param>
        /// <param name="_XmlFileName"></param>
        /// <param name="_idr"></param>
        /// <returns></returns>
        public List<List<Object[]>> Constructer(string _elementTableName, string _XmlFile, IDataReader _idr)
        {
            List<List<Object[]>> reList = new List<List<Object[]>>();
            if (ConstructerXMLPath == null)
            {
                throw new Exception("Constructer ConstructerXMLPath is Null");
            }
            if (ConstructerXMLName == null)
            {
                throw new Exception("Constructer ConstructerXMLName is Null");
            }
            XDocument xdoc = XDocument.Load(_XmlFile);
            if (xdoc != null)
            {
                string strDbType = "";
                if (xdoc.Root.Attribute("dbtype") != null)
                    strDbType = xdoc.Root.Attribute("dbtype").Value;
                var xtable = (from XElement _table in xdoc.Root.Elements("Table")
                              where _table != null &&
                              _table.Attribute("name") != null &&
                              _table.Attribute("name").Value == _elementTableName &&
                              _table.Nodes().Count() > 0
                              select _table).ToList();
                if (xtable != null && xtable.Count == 1 && xtable.Nodes() != null && xtable.Nodes().Count() > 0)
                {
                    while (_idr.Read())
                    {
                        List<Object[]> _tempList = new List<Object[]>();
                        foreach (XElement xelement in xtable.Nodes())
                        {
                            Object[] _tempObject = new Object[] { new Object(), new Object() };
                            if (xelement.Attribute("name") != null)
                                _tempObject[0] = xelement.Attribute("name").Value;
                            if (xelement.Attribute("type") != null)
                                if (_idr[_tempObject[0].ToString()] != null && _idr[_tempObject[0].ToString()].ToString() != "")
                                    _tempObject[1] = getObjectbyDataType(strDbType, _idr[_tempObject[0].ToString()].ToString(), xelement.Attribute("type").Value);
                            _tempList.Add(_tempObject);
                        }
                        reList.Add(_tempList);
                    }
                }
                else
                    throw new Exception("Constructer Load TableName :" + _elementTableName + " field!");
            }
            else
                throw new Exception("Constructer Load XML field!");
            if (reList.Count > 0)
                return reList;
            else
                throw new Exception("Constructer May be the data is null Error!");
        }

        #region 数据格式化
        private object getObjectbyDataType(string dbtype, string datavalue, string datatype)
        {
            EsDataBaseType edbt = (EsDataBaseType)Enum.Parse(typeof(EsDataBaseType), dbtype);
            switch (edbt)
            {
                case EsDataBaseType.OracleClient:
                    return OracleTypeNew(datavalue, datatype);
                case EsDataBaseType.MySqlClient:
                    return MySQLTypeNew(datavalue, datatype);
                case EsDataBaseType.SqlServerClient:
                    return SqlServerTypeNew(datavalue, datatype);
                default:
                    return datavalue;
            }
        }
        private object SqlServerTypeNew(string datavalue, string datatype)
        {
            switch (datatype)
            {
                case "int":
                    return Convert.ToInt32(datavalue);
                case "datetime":
                    return Convert.ToDateTime(datavalue);
                default:
                    return datavalue;
            }
        }
        private object MySQLTypeNew(string datavalue, string datatype)
        {
            switch (datatype)
            {
                case "int":
                    return Convert.ToInt32(datavalue);
                case "date":
                    return Convert.ToDateTime(datavalue);
                default:
                    return datavalue;
            }
        }
        private object OracleTypeNew(string datavalue, string datatype)
        {
            switch (datatype)
            {
                case "DATE":
                    return Convert.ToDateTime(datavalue);
                default:
                    return datavalue;
            }
        }
        #endregion
    }

}
